package com.magicodex.bookkeeping.biz.accounting.util;

import com.magicodex.bookkeeping.biz.accounting.dto.AccountingDTO;
import com.magicodex.bookkeeping.biz.common.util.CheckUtil;
import com.magicodex.bookkeeping.biz.common.util.DateUtil;
import com.magicodex.bookkeeping.biz.common.util.NumberUtil;
import com.magicodex.bookkeeping.biz.common.util.StringUtil;

import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author mh.z
 */
public class AccountingCsvUtil {
    private static final String FIELD_SEPARATOR = "|";
    private static final String LINE_SEPARATOR = "\n";

    /**
     * 序列化成字符串
     *
     * @param records
     * @return
     */
    public static String stringifyAccountingDTOs(List<AccountingDTO> records) {
        CheckUtil.notNull(records, "records null");
        StringBuilder buffer = new StringBuilder();

        for (int index = 0; index < records.size(); index++) {
            AccountingDTO record = records.get(index);

            if (index > 0) {
                buffer.append(LINE_SEPARATOR);
            }

            String content = stringifyAccountingDTO(record);
            buffer.append(content);
        }

        return buffer.toString();
    }

    /**
     * 序列化成字符串
     *
     * @param record
     * @return
     */
    public static String stringifyAccountingDTO(AccountingDTO record) {
        CheckUtil.notNull(record, "record null");
        StringBuilder buffer = new StringBuilder();

        // 账户
        String account = record.getAccount();
        account = StringUtil.trim(account);
        buffer.append(StringUtil.orEmpty(account));

        buffer.append(FIELD_SEPARATOR);
        // 金额
        BigDecimal money = record.getMoney();
        String moneyStr = NumberUtil.formatNumberWithDefaultFmt(money);
        buffer.append(StringUtil.orEmpty(moneyStr));

        buffer.append(FIELD_SEPARATOR);
        // 最后核对日期
        ZonedDateTime date = record.getLastCheckedDate();
        String dateStr = DateUtil.formatYearDay(date);
        buffer.append(StringUtil.orEmpty(dateStr));

        return buffer.toString();
    }

    /**
     * 解析字符串
     *
     * @param text
     * @return
     */
    public static List<AccountingDTO> parseAccountingDTOs(String text) {
        CheckUtil.notNull(text, "text null");

        String[] lines = text.split(LINE_SEPARATOR, -1);
        List<AccountingDTO> recordList = new ArrayList<>(lines.length);

        for (int index = 0; index < lines.length; index++) {
            String line = lines[index];
            line = StringUtil.trim(line);

            if (StringUtil.isNotEmpty(line)) {
                AccountingDTO record = parseAccountingDTO(line);
                recordList.add(record);
            }
        }

        return recordList;
    }

    /**
     * 解析字符串
     *
     * @param text
     * @return
     */
    public static AccountingDTO parseAccountingDTO(String text) {
        CheckUtil.notNull(text, "text null");

        AccountingDTO record = new AccountingDTO();
        int secondSeparatorIndex = text.lastIndexOf(FIELD_SEPARATOR);

        if (secondSeparatorIndex >= 0) {
            // 最后核对日期
            String dateStr = text.substring(secondSeparatorIndex + 1);
            dateStr = StringUtil.trim(dateStr);
            ZonedDateTime date = DateUtil.parseYearDay(dateStr);
            record.setLastCheckedDate(date);

            int firstSeparatorIndex = text.lastIndexOf(FIELD_SEPARATOR, secondSeparatorIndex - 1);
            if (firstSeparatorIndex >= 0) {
                // 账户
                String account = text.substring(0, firstSeparatorIndex);
                account = StringUtil.trim(account);
                record.setAccount(account);

                // 金额
                String moneyStr = text.substring(firstSeparatorIndex + 1, secondSeparatorIndex);
                moneyStr = StringUtil.trim(moneyStr);
                BigDecimal money = NumberUtil.parseNumberWithDefaultFmt(moneyStr);
                record.setMoney(money);
            } else {
                // 账户
                String account = text.substring(0, secondSeparatorIndex);
                account = StringUtil.trim(account);
                record.setAccount(account);
            }
        } else {
            // 账户
            String account = StringUtil.trim(text);
            record.setAccount(account);
        }

        return record;
    }

}
